home *** CD-ROM | disk | FTP | other *** search
/ Experimental BBS Explossion 3 / Experimental BBS Explossion III.iso / c / tde31.zip / HWIND.C < prev    next >
C/C++ Source or Header  |  1993-08-29  |  15KB  |  522 lines

  1. /*******************  start of original comments  ********************/
  2. /*
  3.  * Written by Douglas Thomson (1989/1990)
  4.  *
  5.  * This source code is released into the public domain.
  6.  */
  7.  
  8. /*
  9.  * Name:    hardware independent screen IO module
  10.  * Purpose: This file contains the code to interface the rest of the
  11.  *           editor to the display and input hardware.
  12.  * File:    hwind.c
  13.  * Author:  Douglas Thomson
  14.  * System:  this file is intended to be system-independent
  15.  * Date:    October 2, 1989
  16.  * Notes:   This is the only module that is allowed to call the hardware
  17.  *           dependent display IO library.
  18.  *          Typically, functions here check whether any action is
  19.  *           necessary (for example, the cursor may already happen to be
  20.  *           in the required position), call hardware dependent functions
  21.  *           to achieve the required effect, and finally update status
  22.  *           information about the current state of the terminal display.
  23.  *          The idea behind this approach is to keep the hardware
  24.  *           dependent code as small and simple as possible, thus making
  25.  *           porting the code easier.
  26.  */
  27. /*********************  end of original comments   ********************/
  28.  
  29.  
  30. /*
  31.  * Some routines were added to display current editor modes in the lite bar
  32.  * at the bottom of the screen. Other routines were rewritten in assembly.
  33.  * I feel the need for speed.
  34.  *
  35.  * New editor name:  TDE, the Thomson-Davis Editor.
  36.  * Author:           Frank Davis
  37.  * Date:             June 5, 1991, version 1.0
  38.  * Date:             July 29, 1991, version 1.1
  39.  * Date:             October 5, 1991, version 1.2
  40.  * Date:             January 20, 1992, version 1.3
  41.  * Date:             February 17, 1992, version 1.4
  42.  * Date:             April 1, 1992, version 1.5
  43.  * Date:             June 5, 1992, version 2.0
  44.  * Date:             October 31, 1992, version 2.1
  45.  * Date:             April 1, 1993, version 2.2
  46.  * Date:             June 5, 1993, version 3.0
  47.  * Date:             August 29, 1993, version 3.1
  48.  *
  49.  * This modification of Douglas Thomson's code is released into the
  50.  * public domain, Frank Davis.  You may distribute it freely.
  51.  */
  52.  
  53. #include <bios.h>       /* for REGS */
  54. #include <dos.h>        /* for intdos */
  55.  
  56. #include "tdestr.h"
  57. #include "common.h"
  58. #include "tdefunc.h"
  59. #include "define.h"
  60.  
  61.  
  62. /*
  63.  * Name:    get_date
  64.  * Purpose: get system date from DOS
  65.  * Date:    June 5, 1992
  66.  * Passed:  year:  pointer to integer to store year
  67.  *          month: pointer to integer to store month
  68.  *          day:   pointer to integer to store day
  69.  *          day_of_week:  pointer to integer to store dow
  70.  * Notes:   call standard DOS interrupt 0x21, function 0x2a to get the date.
  71.  */
  72. void get_date( int *year, int *month, int *day, int *day_of_week  )
  73. {
  74. union REGS inregs, outregs;
  75.  
  76.    inregs.h.ah = 0x2a;
  77.    intdos( &inregs, &outregs );
  78.    *year        = (int)outregs.x.cx;
  79.    *month       = (int)outregs.h.dh;
  80.    *day         = (int)outregs.h.dl;
  81.    *day_of_week = (int)outregs.h.al;
  82. }
  83.  
  84.  
  85. /*
  86.  * Name:    get_time
  87.  * Purpose: get system time from DOS
  88.  * Date:    June 5, 1992
  89.  * Passed:  hour:  pointer to integer to store hour - system returns 24 hour
  90.  *          minutes:  pointer to integer to store minutes
  91.  *          seconds:  pointer to integer to store seconds
  92.  *          hundredths:  pointer to integer to store hundredths of second
  93.  * Notes:   call standard DOS interrupt 0x21, function 0x2c to get the time.
  94.  */
  95. void get_time( int *hour, int *minutes, int *seconds, int *hundredths  )
  96. {
  97. union REGS inregs, outregs;
  98.  
  99.    inregs.h.ah = 0x2c;
  100.    intdos( &inregs, &outregs );
  101.    *hour       = (int)outregs.h.ch;
  102.    *minutes    = (int)outregs.h.cl;
  103.    *seconds    = (int)outregs.h.dh;
  104.    *hundredths = (int)outregs.h.dl;
  105. }
  106.  
  107.  
  108. /*
  109.  * Name:    show_modes
  110.  * Purpose: show current editor modes in lite bar at bottom of screen
  111.  * Date:    June 5, 1991
  112.  */
  113. void show_modes( void )
  114. {
  115. char status_line[MAX_COLS+2];
  116.  
  117.    memset( status_line, ' ', MAX_COLS );
  118.    status_line[MAX_COLS] = '\0';
  119.    s_output( status_line, g_display.mode_line, 0, g_display.mode_color );
  120.    s_output( "F=   W=", g_display.mode_line, 1, g_display.mode_color );
  121.    s_output( "m=", g_display.mode_line, 12, g_display.mode_color );
  122.    show_window_count( g_status.window_count );
  123.    show_file_count( g_status.file_count );
  124.    show_avail_mem( );
  125.    show_tab_modes( );
  126.    show_indent_mode( );
  127.    show_sync_mode( );
  128.    show_control_z( );
  129.    show_insert_mode( );
  130.    show_search_case( );
  131.    show_wordwrap_mode( );
  132.    show_trailing( );
  133. }
  134.  
  135.  
  136. /*
  137.  * Name:    show_file_count
  138.  * Purpose: show number of open files in lite bar at bottom of screen
  139.  * Passed:  fc:  file count - number of open files
  140.  * Date:    June 5, 1991
  141.  */
  142. void show_file_count( int fc )
  143. {
  144. char status_line[MAX_COLS+2];
  145.  
  146.    s_output( "  ", g_display.mode_line, 3, g_display.mode_color );
  147.    s_output( itoa( fc, status_line, 10 ), g_display.mode_line, 3,
  148.              g_display.mode_color );
  149. }
  150.  
  151.  
  152. /*
  153.  * Name:    show_window_count
  154.  * Purpose: show total number of windows in lite bar at bottom of screen
  155.  * Passed:  wc:  window count - visible and hidden.
  156.  * Date:    September 13, 1991
  157.  */
  158. void show_window_count( int wc )
  159. {
  160. char status_line[MAX_COLS+2];
  161.  
  162.    s_output( "  ", g_display.mode_line, 8, g_display.mode_color );
  163.    s_output( itoa( wc, status_line, 10 ), g_display.mode_line, 8,
  164.              g_display.mode_color );
  165. }
  166.  
  167.  
  168. /*
  169.  * Name:    show_avail_mem
  170.  * Purpose: show available free memory in lite bar at bottom of screen
  171.  * Date:    June 5, 1991
  172.  */
  173. void show_avail_mem( void )
  174. {
  175. char line[MAX_COLS+2];
  176. unsigned long avail_mem;
  177.  
  178. #if defined( __MSC__ )
  179. unsigned paragraphs;
  180.  
  181.    _dos_allocmem( 0xffff, ¶graphs );
  182.    /*
  183.     * A paragraph is 16 bytes.  Convert paragraphs to bytes by shifting left
  184.     * 4 bits.
  185.     */
  186.    avail_mem = (long)paragraphs << 4;
  187. #else
  188.    avail_mem = farcoreleft( );
  189. #endif
  190.  
  191.    s_output( "        ", g_display.mode_line, 14, g_display.mode_color );
  192.    ultoa( avail_mem, line, 10 );
  193.    s_output( line, g_display.mode_line, 14,
  194.              g_display.mode_color );
  195. }
  196.  
  197.  
  198. /*
  199.  * Name:    show_tab_modes
  200.  * Purpose: show smart tab mode in lite bar at bottom of screen
  201.  * Date:    October 31, 1992
  202.  */
  203. void show_tab_modes( void )
  204. {
  205. char *blank_tab = "   ";
  206. char ascii_tab[10];
  207.  
  208.    s_output( tabs, g_display.mode_line, 22, g_display.mode_color );
  209.    s_output( mode.smart_tab ? smart : fixed, g_display.mode_line, 27,
  210.              g_display.mode_color );
  211.    s_output( mode.inflate_tabs ? intab : outtab, g_display.mode_line, 28,
  212.              g_display.mode_color );
  213.    s_output( blank_tab, g_display.mode_line, 29, g_display.mode_color );
  214.    s_output( itoa( mode.ptab_size, ascii_tab, 10), g_display.mode_line, 29,
  215.              g_display.mode_color );
  216. }
  217.  
  218.  
  219. /*
  220.  * Name:    show_indent_mode
  221.  * Purpose: show indent mode in lite bar at bottom of screen
  222.  * Date:    June 5, 1991
  223.  */
  224. void show_indent_mode( void )
  225. {
  226.    s_output( mode.indent ? indent : blank, g_display.mode_line, 32,
  227.              g_display.mode_color );
  228. }
  229.  
  230.  
  231. /*
  232.  * Name:    show_search_case
  233.  * Purpose: show search mode in lite bar
  234.  * Date:    June 5, 1991
  235.  */
  236. void show_search_case( void )
  237. {
  238.    s_output( mode.search_case == IGNORE ? ignore : match, g_display.mode_line,
  239.              40, g_display.mode_color );
  240. }
  241.  
  242.  
  243. /*
  244.  * Name:    show_sync_mode
  245.  * Purpose: show sync mode in lite bar
  246.  * Date:    January 15, 1992
  247.  */
  248. void show_sync_mode( void )
  249. {
  250.    s_output( mode.sync ? sync_on : sync_off, g_display.mode_line, 48,
  251.              g_display.mode_color );
  252. }
  253.  
  254.  
  255. /*
  256.  * Name:    show_wordwrap_mode
  257.  * Purpose: display state of word wrap mode
  258.  * Date:    June 5, 1991
  259.  */
  260. void show_wordwrap_mode( void )
  261. {
  262.    s_output( ww_mode[mode.word_wrap], g_display.mode_line, 54,
  263.              g_display.mode_color );
  264. }
  265.  
  266.  
  267. /*
  268.  * Name:    show_trailing
  269.  * Purpose: show state of trailing flag
  270.  * Date:    June 5, 1991
  271.  */
  272. void show_trailing( void )
  273. {
  274.    c_output( mode.trailing ? 'T' : ' ', 66, g_display.mode_line,
  275.              g_display.mode_color );
  276. }
  277.  
  278.  
  279. /*
  280.  * Name:    show_control_z
  281.  * Purpose: show state of control z flag
  282.  * Date:    June 5, 1991
  283.  */
  284. void show_control_z( void )
  285. {
  286.    c_output( mode.control_z ? 'Z' : ' ', 77, g_display.mode_line,
  287.              g_display.mode_color );
  288. }
  289.  
  290.  
  291. /*
  292.  * Name:    show_insert_mode
  293.  * Purpose: show insert mode in lite bar
  294.  * Date:    June 5, 1991
  295.  */
  296. void show_insert_mode( void )
  297. {
  298.    c_output( mode.insert ? 'i' : 'o', 79, g_display.mode_line,
  299.              g_display.mode_color );
  300. }
  301.  
  302.  
  303. /*
  304.  * Name:    my_scroll_down
  305.  * Purpose: display a portion of a window
  306.  * Date:    June 5, 1991
  307.  * Passed:  window:  pointer to current window
  308.  * Notes:   Using the bios scroll functions causes a slightly noticable
  309.  *            "flicker", even on fast VGA monitors.  This is caused by changing
  310.  *            the high-lited cursor line to text color then calling the bios
  311.  *            function to scroll.  Then, the current line must then be
  312.  *            hilited.
  313.  *          This function assumes that win->cline is the current line.
  314.  */
  315. void my_scroll_down( WINDOW *window )
  316. {
  317. int  i;
  318. int  curl;
  319. int  eof;
  320. WINDOW w;              /* scratch window struct for dirty work */
  321.  
  322.    if (!window->visible  ||  !g_status.screen_display)
  323.       return;
  324.    dup_window_info( &w, window );
  325.    curl = i = window->bottom_line + 1 - window->cline;
  326.    eof = FALSE;
  327.    for (; i>0; i--) {
  328.       if (w.ll->len != EOF) {
  329.          /*
  330.           * if this is window->cline, do not show the line because we
  331.           * show the curl at the end of this function.  don't show it twice
  332.           */
  333.          if (i != curl)
  334.             update_line( &w );
  335.       } else if (eof == FALSE) {
  336.          show_eof( &w );
  337.          eof = TRUE;
  338.       } else
  339.          window_eol_clear( &w, COLOR_TEXT );
  340.       if (w.ll->next != NULL)
  341.          w.ll = w.ll->next;
  342.       ++w.cline;
  343.       ++w.rline;
  344.    }
  345.    show_curl_line( window );
  346. }
  347.  
  348.  
  349. /*
  350.  * Name:    combine_strings
  351.  * Purpose: stick 3 strings together
  352.  * Date:    June 5, 1991
  353.  * Passed:  buff:    buffer to hold concatenation of 3 strings
  354.  *          s1:  pointer to string 1
  355.  *          s2:  pointer to string 2
  356.  *          s3:  pointer to string 3
  357.  */
  358. void combine_strings( char *buff, char *s1, char *s2, char *s3 )
  359. {
  360.    assert( strlen( s1 ) + strlen( s2 ) + strlen( s3 ) < MAX_COLS );
  361.    strcpy( buff, s1 );
  362.    strcat( buff, s2 );
  363.    strcat( buff, s3 );
  364. }
  365.  
  366.  
  367. /*
  368.  * Name:    make_ruler
  369.  * Purpose: make ruler with tabs, tens, margins, etc...
  370.  * Date:    June 5, 1991
  371.  * Passed:  window:  pointer to current window
  372.  */
  373. void make_ruler( WINDOW *window )
  374. {
  375. register WINDOW *win;
  376. char num[20];
  377. register unsigned char *p;
  378. int  len;
  379. int  col;
  380. int  i;
  381. int  mod;
  382.  
  383.    win = window;
  384.  
  385.    /*
  386.     * need to have a least two lines in a window when we display a ruler.
  387.     */
  388.    if (win->bottom_line - win->top_line < 1)
  389.       win->ruler = FALSE;
  390.    if (win->ruler) {
  391.  
  392.       /*
  393.        * find the width of the window and fill the ruler with dots.
  394.        */
  395.       len = win->end_col + 1 - win->start_col;
  396.  
  397.       assert( len >= 0 );
  398.       assert( len <= MAX_COLS );
  399.  
  400.       memset( win->ruler_line, RULER_FILL, len );
  401.       win->ruler_line[len] = '\0';
  402.       col = win->bcol+1;
  403.  
  404.       assert( col >= 1 );
  405.       assert( col <= MAX_LINE_LENGTH );
  406.  
  407.       for (p=(unsigned char *)win->ruler_line; *p; col++, p++) {
  408.  
  409.          /*
  410.           * put a tens digit in the tens column
  411.           */
  412.          mod = col % 10;
  413.          if (mod == 0) {
  414.             itoa( col/10, num, 10 );
  415.  
  416.             /*
  417.              * let the margin chars have precidence over tens digit
  418.              */
  419.             for (i=0; num[i] && *p; col++, i++) {
  420.                if (col == mode.left_margin+1)
  421.                   *p = LM_CHAR;
  422.                else if (col == mode.right_margin+1) {
  423.                   if (mode.right_justify == TRUE)
  424.                      *p = RM_CHAR_JUS;
  425.                   else
  426.                      *p = RM_CHAR_RAG;
  427.                } else if (col == mode.parg_margin+1)
  428.                   *p = PGR_CHAR;
  429.                else
  430.                   *p = num[i];
  431.                p++;
  432.             }
  433.  
  434.             /*
  435.              * we may have come to the end of the ruler in the for loop.
  436.              */
  437.             if (*p == '\0')
  438.                break;
  439.          } else if (mod == 5)
  440.             *p = RULER_TICK;
  441.          if (col == mode.parg_margin+1)
  442.             *p = PGR_CHAR;
  443.          if (col == mode.left_margin+1)
  444.             *p = LM_CHAR;
  445.          else if (col == mode.right_margin+1) {
  446.             if (mode.right_justify == TRUE)
  447.                *p = RM_CHAR_JUS;
  448.             else
  449.                *p = RM_CHAR_RAG;
  450.          }
  451.       }
  452.    }
  453. }
  454.  
  455.  
  456. /*
  457.  * Name:    show_ruler
  458.  * Purpose: show ruler with tens, margins, etc...
  459.  * Date:    June 5, 1991
  460.  * Passed:  window:  pointer to current window
  461.  */
  462. void show_ruler( WINDOW *window )
  463. {
  464.    if (window->ruler && window->visible)
  465.       s_output( window->ruler_line, window->top_line, window->start_col,
  466.                 g_display.ruler_color );
  467. }
  468.  
  469.  
  470. /*
  471.  * Name:    show_ruler_char
  472.  * Purpose: show ruler character under ruler pointer
  473.  * Date:    June 5, 1991
  474.  * Passed:  window:  pointer to current window
  475.  */
  476. void show_ruler_char( WINDOW *window )
  477. {
  478. register WINDOW *win;
  479. char c;
  480.  
  481.    win = window;
  482.    if (win->ruler && win->visible) {
  483.       c = win->ruler_line[win->ccol - win->start_col];
  484.       c_output( c, win->ccol, win->top_line, g_display.ruler_color );
  485.    }
  486. }
  487.  
  488.  
  489. /*
  490.  * Name:    show_ruler_pointer
  491.  * Purpose: show ruler pointer
  492.  * Date:    June 5, 1991
  493.  * Passed:  window:  pointer to current window
  494.  */
  495. void show_ruler_pointer( WINDOW *window )
  496. {
  497.    if (window->ruler && window->visible)
  498.       c_output( RULER_PTR, window->ccol, window->top_line,
  499.                 g_display.ruler_pointer );
  500. }
  501.  
  502.  
  503. /*
  504.  * Name:    show_all_rulers
  505.  * Purpose: make and show all rulers in all visible windows
  506.  * Date:    June 5, 1991
  507.  */
  508. void show_all_rulers( void )
  509. {
  510. register WINDOW *wp;
  511.  
  512.    wp = g_status.window_list;
  513.    while (wp != NULL) {
  514.       make_ruler( wp );
  515.       if (wp->visible) {
  516.          show_ruler( wp );
  517.          show_ruler_pointer( wp );
  518.       }
  519.       wp = wp->next;
  520.    }
  521. }
  522.